package service

import (
	set "github.com/deckarep/golang-set"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"shrimp-blog-server/app/dao"
	"shrimp-blog-server/app/model"
)

//nolint:funlen
func (server LabelService) AddLabel(req *ghttp.Request, labels ...model.LabelRequest) {
	if len(labels) == 0 {
		responses.ErrorResponseExit(req, "请输入标签信息")
	}
	var labelModel []model.Label

	// 检测标签是否存在
	oldSet := set.NewSet()
	for i := range labels {
		oldSet.Add(labels[i].Name)
	}
	err := dao.Label.DB().Model(dao.Label.Table).Where(g.Map{dao.Label.Columns.Name: oldSet.ToSlice()}).WhereNotNull(dao.Label.Columns.DeleteTime).Unscoped().Scan(&labelModel)
	if err != nil {
		panic(gerror.Wrap(err, "查询标签失败"))
	}
	if len(labelModel) > 0 {
		tx, err := dao.Label.DB().Begin()
		if err != nil {
			panic(gerror.Wrap(err, "开启事务失败"))
		}
		for i := range labelModel {
			labelModel[i].Status = 1
			labelModel[i].DeleteTime = nil
			_, err := dao.Label.DB().Model(dao.Label.Table).TX(tx).Where(g.Map{dao.Label.Columns.Id: labelModel[i].Id}).WhereNotNull(dao.Label.Columns.DeleteTime).Unscoped().Update(labelModel[i])
			if err != nil {
				g.Log("添加标签").Error(gerror.Wrap(err, "更新标签失败"))
			}
		}
		if err != nil {
			err := tx.Rollback()
			if err != nil {
				panic(gerror.Wrap(err, "回滚事务失败"))
			}
		} else {
			err := tx.Commit()
			if err != nil {
				panic(gerror.Wrap(err, "提交事务失败"))
			}
		}

		newSet := set.NewSet()
		for i := range labelModel {
			newSet.Add(labelModel[i].Name)
		}

		// 不一样的标签
		difference := oldSet.Difference(newSet)

		if len(difference.ToSlice()) > 0 {
			labelModel = make([]model.Label, 0)
			for i := range difference.ToSlice() {
				labelModel = append(labelModel, model.Label{Name: difference.ToSlice()[i].(string)})
			}
			_, err = dao.Label.Insert(labelModel...)
			if err != nil {
				g.Log("添加标签").Error(gerror.Wrap(err, "添加标签失败"))
				responses.ErrorResponseExit(req, "插入标签失败")
				req.ExitAll()
			}
		}
	} else {
		for i := range labels {
			labelModel = append(labelModel, model.Label{Name: labels[i].Name, Status: model.ShowStatus})
		}
		_, err := dao.Label.Insert(labelModel...)
		if err != nil {
			g.Log("添加标签").Error(gerror.Wrap(err, "添加标签失败"))
			responses.ErrorResponseExit(req, "插入标签失败")
			req.ExitAll()
		}
	}

	responses.SuccessResponse(req)
}

func (server LabelService) DeleteLabel(req *ghttp.Request, ids ...uint) {
	if len(ids) == 0 {
		responses.ErrorResponseExit(req, "请输入标签信息")
	}
	models := make([]model.Label, len(ids))
	for i, id := range ids {
		models[i] = model.Label{Id: id, Status: model.NotShowStatus}
	}

	result, err := dao.Label.Delete(models...)

	if err != nil {
		g.Log("删除标签失败").Error(err)
		panic(gerror.Wrap(err, "删除标签失败"))
	}
	if result == 0 {
		responses.ErrorResponseExit(req, "删除标签失败")
	}
	responses.SuccessResponse(req)
}
func (server LabelService) UpdateLabel(req *ghttp.Request, label ...model.LabelRequest) {
	if len(label) == 0 {
		responses.ErrorResponseExit(req, "请选择要修改的标签")
	}

	tx, err := dao.Label.DB().Begin()
	if err != nil {
		panic(gerror.Wrap(err, "开启事务失败"))
	}
	for i := range label {
		_, err := dao.Label.Update(tx, label[i].Convert())
		if err != nil {
			g.Log("修改标签失败").Error(err)
		}
	}
	if err != nil {
		err := tx.Rollback()
		if err != nil {
			panic(gerror.Wrap(err, "回滚事务失败"))
		}
	} else {
		err := tx.Commit()
		if err != nil {
			panic(gerror.Wrap(err, "提交事务失败"))
		}
	}

	responses.SuccessResponse(req)
}
func (server LabelService) GetLabel(req *ghttp.Request, ids ...uint) {
	if len(ids) == 0 {
		responses.ErrorResponseExit(req, "请选择要查询的标签")
	}

	result, err := dao.Label.GetModelById(ids...)
	if err != nil {
		g.Log("查询标签失败").Error(err)
		panic(err)
	}
	if result == nil {
		responses.ErrorResponseExit(req, "获取标签失败")
	}
	if len(result) == 1 {
		responses.Json(req, successCode, successMessage, (&model.LabelResponse{}).Convert(&result[0]))
		req.ExitAll()
	}
	responses.Json(req, successCode, successMessage, result[0].Convert(result))
}
func (server LabelService) GetLabelPage(req *ghttp.Request, page model.Page) {
	result, err := dao.Label.GetModelsByPage(page.Page, page.Size)
	if err != nil {
		g.Log("查询标签失败").Error(err)
		panic(err)
	}
	if result == nil {
		responses.ErrorResponseExit(req, "标签列表为空")
	}

	labelResponsePage := result[0].ConvertPage(result, page)
	labelResponsePage.Page.Total, err = dao.Label.DB().Model(dao.Label.Table).Count()
	if err != nil {
		panic(gerror.Wrap(err, "统计数量失败"))
	}
	responses.Json(req, successCode, successMessage, labelResponsePage)
}
